const mysql = require('mysql2/promise');
const fs = require('fs');
const path = require('path');

// 获取配置文件路径的统一函数
function getConfigPath(filename) {
  // 尝试多个可能的配置文件位置
  const possiblePaths = [
    // 1. resources 目录（打包后的外置配置）
    path.join(process.resourcesPath || '', filename),
    // 2. app.asar.unpacked 目录
    path.join(__dirname, '..', 'app.asar.unpacked', filename),
    // 3. 相对路径（开发环境）
    path.join(__dirname, filename),
    // 4. 执行目录下的 resources
    path.join(path.dirname(process.execPath), 'resources', filename),
    // 5. 应用目录下
    path.join(path.dirname(process.execPath), filename),
    // 6. resources 子目录
    path.join(__dirname, '..', 'resources', filename)
  ];

  // 找到第一个存在的配置文件
  for (const testPath of possiblePaths) {
    if (fs.existsSync(testPath)) {
      console.log(`使用配置文件: ${testPath}`);
      return testPath;
    }
  }
  
  // 如果都没找到，返回第一个路径（用于创建默认配置）
  console.log(`配置文件未找到，将使用默认路径: ${possiblePaths[0]}`);
  return possiblePaths[0];
}

/**
 * 数据库服务类
 * 提供数据库连接管理和值班数据查询功能
 */
class DatabaseService {
  constructor() {
    this.connection = null;
    this.config = null;
    this.isConnected = false;
    this.reconnectAttempts = 0;
    this.maxReconnectAttempts = 5;
    this.reconnectDelay = 5000; // 5秒重连间隔
  }

  /**
   * 加载数据库配置
   * @returns {Object} 数据库配置
   */
  loadConfig() {
    try {
      const configPath = getConfigPath('config.json');
      const configData = fs.readFileSync(configPath, 'utf8');
      const config = JSON.parse(configData);
      
      if (!config.database) {
        throw new Error('数据库配置未找到');
      }
      
      this.config = config.database;
      console.log('数据库配置加载成功:', {
        host: this.config.host,
        port: this.config.port,
        database: this.config.database
      });
      
      return this.config;
    } catch (error) {
      console.error('加载数据库配置失败:', error.message);
      throw error;
    }
  }

  /**
   * 建立数据库连接
   * @returns {Promise<boolean>} 连接是否成功
   */
  async connect() {
    try {
      if (this.isConnected && this.connection) {
        return true;
      }

      if (!this.config) {
        this.loadConfig();
      }

      console.log('正在连接数据库...');
      
      this.connection = await mysql.createConnection({
        host: this.config.host,
        port: this.config.port,
        user: this.config.user,
        password: this.config.password,
        database: this.config.database,
        charset: this.config.charset || 'utf8mb4',
        acquireTimeout: 10000,
        timeout: 10000,
        reconnect: true
      });

      this.isConnected = true;
      this.reconnectAttempts = 0;
      console.log('数据库连接成功');
      
      return true;
    } catch (error) {
      this.isConnected = false;
      this.connection = null;
      console.error('数据库连接失败:', error.message);
      
      // 自动重连逻辑
      if (this.reconnectAttempts < this.maxReconnectAttempts) {
        this.reconnectAttempts++;
        console.log(`${this.reconnectDelay / 1000}秒后尝试第${this.reconnectAttempts}次重连...`);
        
        setTimeout(() => {
          this.connect();
        }, this.reconnectDelay);
      } else {
        console.error('已达到最大重连次数，停止重连');
      }
      
      return false;
    }
  }

  /**
   * 断开数据库连接
   */
  async disconnect() {
    try {
      if (this.connection) {
        await this.connection.end();
        this.connection = null;
        this.isConnected = false;
        console.log('数据库连接已断开');
      }
    } catch (error) {
      console.error('断开数据库连接时出错:', error.message);
    }
  }

  /**
   * 测试数据库连接
   * @returns {Promise<Object>} 测试结果
   */
  async testConnection() {
    try {
      const success = await this.connect();
      if (success) {
        // 执行一个简单查询来验证连接
        const [rows] = await this.connection.execute('SELECT 1 as test');
        return {
          success: true,
          message: '数据库连接正常',
          timestamp: new Date().toISOString()
        };
      } else {
        return {
          success: false,
          message: '数据库连接失败',
          timestamp: new Date().toISOString()
        };
      }
    } catch (error) {
      return {
        success: false,
        message: `连接测试失败: ${error.message}`,
        timestamp: new Date().toISOString()
      };
    }
  }

  /**
   * 生成模拟值班数据
   * @param {string} date - 日期
   * @returns {Object} 模拟的值班数据
   */
  generateMockData(date = null) {
    try {
      const targetDate = date || new Date().toISOString().split('T')[0];
      
      // 从配置文件读取模拟数据
      let mockDataConfig;
      
      // 尝试多个可能的配置文件路径
      const possibleConfigPaths = [
        // 1. electron 目录下的配置文件（开发环境）
        path.join(__dirname, 'config-duty.json'),
        // 2. 使用getConfigPath函数获取路径
        getConfigPath('config-duty.json'),
        // 3. 项目根目录下的electron目录
        path.join(__dirname, '..', 'electron', 'config-duty.json'),
        // 4. 相对路径
        path.join(process.cwd(), 'electron', 'config-duty.json')
      ];
      
      let configPath = null;
      for (const testPath of possibleConfigPaths) {
        if (fs.existsSync(testPath)) {
          configPath = testPath;
          console.log(`找到配置文件: ${configPath}`);
          break;
        }
      }
      
      if (configPath) {
        try {
          const configData = fs.readFileSync(configPath, 'utf8');
          const config = JSON.parse(configData);
          mockDataConfig = config.mockData;
          console.log('从配置文件读取到模拟数据:', {
            configPath,
            mockDataCount: mockDataConfig ? mockDataConfig.length : 0
          });
        } catch (parseError) {
          console.error('解析配置文件失败:', parseError.message);
        }
      } else {
        console.warn('未找到config-duty.json配置文件，尝试的路径:', possibleConfigPaths);
      }
      
      // 如果配置文件中没有模拟数据，使用默认数据
      if (!mockDataConfig) {
        console.warn('配置文件中未找到模拟数据，使用默认模拟数据');
        mockDataConfig = [
          {
            name: '张三',
            phone: '13800138001',
            department: '指挥中心',
            remarks: '临时指挥长'
          },
          {
            name: '李四',
            phone: '13800138002',
            department: '治安大队',
            remarks: ''
          },
          {
            name: '王五',
            phone: '13800138003',
            department: '刑侦大队',
            remarks: ''
          },
          {
            name: '赵六',
            phone: '13800138004',
            department: '交警大队',
            remarks: ''
          }
        ];
      }
      
      const mockData = {
        date: targetDate,
        persons: mockDataConfig || []
      };

      console.log('从配置文件生成模拟值班数据:', {
        date: targetDate,
        totalPersons: mockData.persons.length,
        configPath: configPath
      });

      return mockData;
    } catch (error) {
      console.error('生成模拟数据失败:', error.message);
      // 返回空的模拟数据结构
      return {
        date: date || new Date().toISOString().split('T')[0],
        persons: []
      };
    }
  }

  /**
   * 获取值班数据
   * @param {string} date - 日期 (可选，默认为今天)
   * @param {boolean} useMockData - 是否使用模拟数据
   * @returns {Promise<Object>} 值班数据
   */
  async getDutyData(date = null, useMockData = false) {
    try {
      // 如果使用模拟数据，直接返回模拟数据
      if (useMockData) {
        return this.generateMockData(date);
      }

      if (!this.isConnected) {
        await this.connect();
      }

      if (!this.isConnected) {
        throw new Error('数据库未连接');
      }

      // 如果没有指定日期，使用今天
      const targetDate = date || new Date().toISOString().split('T')[0];
      
      console.log('查询值班数据，日期:', targetDate);

      // 查询值班数据，关联管理员和部门表
      const query = `
        SELECT 
          d.date,
          a.name,
          a.phone,
          a.photo,
          a.department_id,
          dept.name as department_name,
          d.remarks
        FROM duty d
        LEFT JOIN admin a ON d.admin_id = a.id
        LEFT JOIN department dept ON a.department_id = dept.id
        WHERE d.date = ?
        ORDER BY d.sort ASC, a.name
      `;

      const [rows] = await this.connection.execute(query, [targetDate]);
      
      // 统一返回人员数组
      const dutyData = {
        date: targetDate,
        persons: rows.map(row => ({
          name: row.name || '未指定',
          phone: row.phone || '未指定',
          photo: row.photo || '',
          department: row.department_name || '未指定',
          remarks: row.remarks || ''
        }))
      };

      console.log('值班数据查询完成:', {
        date: targetDate,
        totalPersons: dutyData.persons.length
      });

      return dutyData;

    } catch (error) {
      console.error('获取值班数据失败:', error.message);
      throw error;
    }
  }

  /**
   * 获取管理员列表
   * @returns {Promise<Array>} 管理员列表
   */
  async getAdminList() {
    try {
      if (!this.isConnected) {
        await this.connect();
      }

      const query = `
        SELECT 
          a.id,
          a.name,
          a.phone,
          a.photo,
          a.department_id,
          dept.name as department_name
        FROM admin a
        LEFT JOIN department dept ON a.department_id = dept.id
        ORDER BY a.name
      `;

      const [rows] = await this.connection.execute(query);
      return rows;

    } catch (error) {
      console.error('获取管理员列表失败:', error.message);
      throw error;
    }
  }

  /**
   * 获取部门列表
   * @returns {Promise<Array>} 部门列表
   */
  async getDepartmentList() {
    try {
      if (!this.isConnected) {
        await this.connect();
      }

      const query = `
        SELECT id, name, description
        FROM department
        ORDER BY name
      `;

      const [rows] = await this.connection.execute(query);
      return rows;

    } catch (error) {
      console.error('获取部门列表失败:', error.message);
      throw error;
    }
  }

  /**
   * 执行自定义查询
   * @param {string} query - SQL查询语句
   * @param {Array} params - 查询参数
   * @returns {Promise<Array>} 查询结果
   */
  async executeQuery(query, params = []) {
    try {
      if (!this.isConnected) {
        await this.connect();
      }

      console.log('执行查询:', query);
      const [rows] = await this.connection.execute(query, params);
      return rows;

    } catch (error) {
      console.error('执行查询失败:', error.message);
      throw error;
    }
  }

  /**
   * 获取连接状态
   * @returns {Object} 连接状态信息
   */
  getConnectionStatus() {
    return {
      isConnected: this.isConnected,
      config: this.config ? {
        host: this.config.host,
        port: this.config.port,
        database: this.config.database
      } : null,
      reconnectAttempts: this.reconnectAttempts,
      maxReconnectAttempts: this.maxReconnectAttempts
    };
  }
}

// 创建单例实例
const dbService = new DatabaseService();

module.exports = dbService;